package cn.iocoder.yudao.module.book.service.classes;

import cn.iocoder.yudao.module.book.controller.app.classes.vo.AppClassDetailRespVO;
import cn.iocoder.yudao.module.book.controller.app.classes.vo.AppClassMembersSaveReqVO;
import cn.iocoder.yudao.module.book.controller.app.classes.vo.AppClassesSaveReqVO;
import cn.iocoder.yudao.module.book.controller.app.classes.vo.AppClassesRespVO;
import cn.iocoder.yudao.module.book.controller.app.classes.vo.BanjiManageReqVO;
import cn.iocoder.yudao.module.book.controller.app.classes.vo.AppClassMemberRespVO;
import cn.iocoder.yudao.module.book.dal.dataobject.members.ClassMembersDO;
import cn.iocoder.yudao.module.book.dal.dataobject.users.userDTODO;
import cn.iocoder.yudao.module.book.dal.mysql.classesAndMember.ClassesAndMemberMapper;
import cn.iocoder.yudao.module.book.dal.mysql.members.ClassMembersMapper;
import cn.iocoder.yudao.module.book.service.members.ClassMembersService;
import cn.iocoder.yudao.module.book.service.users.userDTOService;
import cn.iocoder.yudao.module.book.controller.app.lock.vo.AppCheckInEnhancedRespVO;
import cn.iocoder.yudao.module.book.controller.app.bookcase.vo.AppBooksRespVO;
import cn.iocoder.yudao.module.book.service.books.BooksService;
import cn.iocoder.yudao.module.book.constants.UserConstants;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.book.controller.admin.classes.vo.*;
import cn.iocoder.yudao.module.book.dal.dataobject.classes.ClassesDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.book.dal.mysql.classes.ClassesMapper;
import cn.iocoder.yudao.module.book.dal.dataobject.homeworks.HomeworksDO;
import cn.iocoder.yudao.module.book.dal.mysql.homeworks.HomeworksMapper;
import cn.iocoder.yudao.module.book.dal.dataobject.checkIn.CheckInDO;
import cn.iocoder.yudao.module.book.dal.mysql.checkIn.CheckInMapper;
import java.util.stream.Collectors;
import java.util.function.Function;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.book.enums.ErrorCodeConstants.*;

/**
 * 班级 Service 实现类
 *
 * @author xi
 */
@Service
@Validated
public class ClassesServiceImpl implements ClassesService {

    @Resource
    private ClassesMapper classesMapper;

    @Resource
    private userDTOService userService;

    @Resource
    private ClassMembersMapper classMembersMapper;

    @Resource
    private BooksService booksService;

    @Resource
    private ClassMembersService classMembersService;

    @Resource
    private ClassesAndMemberMapper classesAndMemberMapper;

    @Resource
    private HomeworksMapper homeworksMapper;

    // 注释掉不存在的 HomeworkMembersMapper
    // @Resource
    // private HomeworkMembersMapper homeworkMembersMapper;

    @Resource
    private CheckInMapper checkInMapper;
    @Override
    public Integer createClasses(ClassesSaveReqVO createReqVO) {
        // 插入
        ClassesDO classes = BeanUtils.toBean(createReqVO, ClassesDO.class);
        classesMapper.insert(classes);
        // 返回
        return classes.getClassesId();
    }

    @Override
    public void updateClasses(ClassesSaveReqVO updateReqVO) {
        // 校验存在
        validateClassesExists(updateReqVO.getClassesId());
        // 更新
        ClassesDO updateObj = BeanUtils.toBean(updateReqVO, ClassesDO.class);
        classesMapper.updateById(updateObj);
    }

    @Override
    public void deleteClasses(Integer id) {
        // 校验存在
        validateClassesExists(id);
        // 删除
        classesMapper.deleteById(id);
    }

    private void validateClassesExists(Integer id) {
        if (classesMapper.selectById(id) == null) {
            throw exception(CLASSES_NOT_EXISTS);
        }
    }

    @Override
    public ClassesDO getClasses(Integer id) {
        return classesMapper.selectById(id);
    }

    @Override
    public PageResult<ClassesDO> getClassesPage(ClassesPageReqVO pageReqVO) {
        return classesMapper.selectPage(pageReqVO);
    }

    @Override
    public Integer InsertClasses(AppClassesSaveReqVO clas) {
        clas.setCreateTime(LocalDateTime.now());
        clas.setUpdateTime(LocalDateTime.now());
        clas.setCommand(generateClassCode());
        ClassesDO classes = BeanUtils.toBean(clas, ClassesDO.class);
        classesMapper.insert(classes);
        Integer id=classes.getClassesId();
        AppClassMembersSaveReqVO member=new AppClassMembersSaveReqVO();
        member.setClassesId(id);
        member.setUserId(Long.valueOf(classes.getUserId()));
        classMembersService.InsertClassMembers( member);
        return classes.getClassesId();
    }

    @Override
    public ClassesDO selectClasses(Integer command) {
        return classesMapper.selectOne(ClassesDO::getCommand, command);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String manageClass(BanjiManageReqVO reqVO, Long currentUserId) {
        // 校验班级是否存在
        ClassesDO banji = classesMapper.selectById(reqVO.getClassId());
        if (banji == null) {
            throw exception(BANJI_NOT_EXISTS);
        }
        
        // 校验班级管理权限（只有班主任可以管理）
        if (!banji.getUserId().equals(currentUserId.intValue())) {
            throw exception(BANJI_NOT_YOURS);
        }
        
        String result;
        switch (reqVO.getOperateType()) {
            case 1:
                // 转让班级
                result = transferClass(banji, reqVO, currentUserId);
                break;
            case 2:
                // 锁定班级
                result = lockClass(banji, reqVO);
                break;
            case 3:
                // 解锁班级
                result = unlockClass(banji);
                break;
            case 4:
                // 解散班级
                result = dissolveClass(banji);
                // 解散后强制验证最新状态
                System.out.println("解散操作完成，强制验证最新状态");
                Boolean finalDeleted = classesMapper.checkClassDeleted(reqVO.getClassId());
                System.out.println("强制刷新后班级状态: deleted=" + finalDeleted);
                break;
            case 5:
                // 移除成员
                result = removeMember(banji, reqVO);
                break;
            case 6:
                // 修改班级名称
                result = modifyClassName(banji, reqVO);
                break;
            default:
                throw new RuntimeException("不支持的操作类型");
        }
        
        return result;
    }
    
    private String transferClass(ClassesDO banji, BanjiManageReqVO reqVO, Long currentUserId) {
        if (reqVO.getNewOwnerId() == null) {
            throw new RuntimeException("请选择新的班主任");
        }
        
        // 检查新班主任是否是班级成员
        ClassMembersDO newOwnerMember = classMembersMapper.selectOne(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getClassesId, banji.getClassesId())
                .eq(ClassMembersDO::getUserId, reqVO.getNewOwnerId())
                .eq(ClassMembersDO::getDeleted, false)
        );
        
        if (newOwnerMember == null) {
            throw new RuntimeException("选择的用户不是班级成员");
        }
        
        // 更新班级所有者
        banji.setUserId(reqVO.getNewOwnerId().intValue()); // 转换为Integer
        if (reqVO.getNewClassName() != null && !reqVO.getNewClassName().trim().isEmpty()) {
            banji.setCname(reqVO.getNewClassName());
        }
        classesMapper.updateById(banji);
        
        // 更新新班主任的成员角色
        // newOwnerMember.setIsTeacher(true); // 暂时注释，根据实际字段调整
        classMembersMapper.updateById(newOwnerMember);
        
        // 更新原班主任的成员角色（如果原班主任还在班级中）
        ClassMembersDO oldOwnerMember = classMembersMapper.selectOne(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getClassesId, banji.getClassesId())
                .eq(ClassMembersDO::getUserId, currentUserId.intValue())
                .eq(ClassMembersDO::getDeleted, false)
        );
        
        if (oldOwnerMember != null) {
            // oldOwnerMember.setIsTeacher(false); // 暂时注释，根据实际字段调整
            classMembersMapper.updateById(oldOwnerMember);
        }
        
        return "班级转让成功";
    }
    
    private String lockClass(ClassesDO banji, BanjiManageReqVO reqVO) {
        // banji.setStatus(0); // 暂时注释，根据实际字段调整
        // banji.setLockReason(reqVO.getLockReason()); // 如果有lockReason字段的话
        classesMapper.updateById(banji);
        return "班级已锁定";
    }
    
    private String unlockClass(ClassesDO banji) {
        // banji.setStatus(1); // 暂时注释，根据实际字段调整
        // banji.setLockReason(null); // 如果有lockReason字段的话
        classesMapper.updateById(banji);
        return "班级已解锁";
    }
    
    private String dissolveClass(ClassesDO banji) {
        System.out.println("=== 解散班级调试信息 ===");
        System.out.println("解散班级ID: " + banji.getClassesId());
        System.out.println("班级名称: " + banji.getCname());
        System.out.println("解散前deleted状态: " + banji.getDeleted());
        
        // 使用直接SQL软删除班级，避免bit字段更新问题
        classesMapper.deleteClassById(banji.getClassesId());
        System.out.println("班级表已通过直接SQL删除");
        
        // 验证班级删除状态 - 使用专门的验证方法
        Boolean isDeleted = classesMapper.checkClassDeleted(banji.getClassesId());
        System.out.println("验证班级删除状态: deleted=" + isDeleted);
        
        // 使用直接SQL删除所有成员关系
        classMembersMapper.deleteMembersByClassId(banji.getClassesId());
        System.out.println("班级成员关系已通过直接SQL删除");
        
        // 验证成员关系删除状态
        List<ClassMembersDO> remainingMembers = classMembersMapper.selectList(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getClassesId, banji.getClassesId())
                .eq(ClassMembersDO::getDeleted, false)
        );
        System.out.println("删除后剩余活跃成员关系数量: " + remainingMembers.size());
        
        System.out.println("=== 解散班级调试信息结束 ===");
        return "班级已解散";
    }
    
    private String modifyClassName(ClassesDO banji, BanjiManageReqVO reqVO) {
        if (reqVO.getNewClassName() == null || reqVO.getNewClassName().trim().isEmpty()) {
            throw new RuntimeException("班级名称不能为空");
        }
        
        String newName = reqVO.getNewClassName().trim();
        if (newName.length() > 20) {
            throw new RuntimeException("班级名称不能超过20个字符");
        }
        
        String oldName = banji.getCname();
        banji.setCname(newName);
        classesMapper.updateById(banji);
        
        return "班级名称已从 \"" + oldName + "\" 修改为 \"" + newName + "\"";
    }
    
    private String removeMember(ClassesDO banji, BanjiManageReqVO reqVO) {
        if (reqVO.getMemberId() == null) {
            throw new RuntimeException("请选择要移除的成员");
        }
        
        // 不能移除班主任自己
        if (reqVO.getMemberId().equals(banji.getUserId())) {
            throw new RuntimeException("不能移除班主任");
        }
        
        // 查找要移除的成员
        ClassMembersDO memberToRemove = classMembersMapper.selectOne(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getClassesId, banji.getClassesId())
                .eq(ClassMembersDO::getUserId, reqVO.getMemberId())
                .eq(ClassMembersDO::getDeleted, false)
        );
        
        if (memberToRemove == null) {
            throw new RuntimeException("成员不存在或已被移除");
        }
        
        // 软删除成员
        memberToRemove.setDeleted(true);
        classMembersMapper.updateById(memberToRemove);
        
        return "成员已移除";
    }

    @Override
    public List<ClassesDO> getClassByUserId(Long currentUserId) {
        return classesMapper.getClassByUserId(currentUserId);
    }

    @Override
    public Integer getCommand(Integer classesId) {
        return classesMapper.getCommand(classesId);
    }


    public Integer generateClassCode() {
        Random random = new Random();
        int maxTry = 10; // 最多尝试次数
        for (int i = 0; i < maxTry; i++) {
            int code = random.nextInt(900000) + 100000; // 生成 100000 ~ 999999 之间的随机数
            if (!classesMapper.selectByClassCode(code)) {
                return code;
            }
        }
        throw new RuntimeException("无法生成唯一口令，请稍后再试");
    }

    @Override
    public AppClassDetailRespVO getClassDetail(Integer classId, Long userId) {
        // 1. 获取班级基本信息
        ClassesDO classesDO = classesMapper.selectById(classId);
        if (classesDO == null) {
            throw exception(BANJI_NOT_EXISTS);
        }

        AppClassDetailRespVO detail = new AppClassDetailRespVO();

        // 2. 构建班级基本信息
        AppClassDetailRespVO.ClassInfo classInfo = new AppClassDetailRespVO.ClassInfo();
        classInfo.setClassesId(classesDO.getClassesId());
        classInfo.setCname(classesDO.getCname());
        classInfo.setUserId(Long.valueOf(classesDO.getUserId()));
        classInfo.setCommand(classesDO.getCommand());
        classInfo.setCreateTime(classesDO.getCreateTime());
        classInfo.setIsTeacher(userId.equals(Long.valueOf(classesDO.getUserId())));
        
        // 获取老师姓名
        userDTODO teacher = userService.getuserDTO(Long.valueOf(classesDO.getUserId()));
        classInfo.setTeacherName(teacher != null ? teacher.getNickname() : "未知");

        // 3. 获取班级成员
        List<ClassMembersDO> memberDOs = classMembersMapper.selectList(ClassMembersDO::getClassesId, classId);
        List<AppClassDetailRespVO.ClassMember> members = new ArrayList<>();
        
        for (ClassMembersDO memberDO : memberDOs) {
            if (memberDO.getDeleted()) continue; // 跳过已删除成员
            
            AppClassDetailRespVO.ClassMember member = new AppClassDetailRespVO.ClassMember();
            member.setMembersId(memberDO.getMembersId());
            member.setUserId(Long.valueOf(memberDO.getUserId()));
            member.setJoinTime(memberDO.getCreateTime());
            member.setIsTeacher(memberDO.getUserId().equals(classesDO.getUserId()));
            
            // 获取用户信息
            userDTODO user = userService.getuserDTO(Long.valueOf(memberDO.getUserId()));
            if (user != null) {
                member.setNickname(user.getNickname());
                member.setAvatar(user.getAvatarUrl());
            }
            
            members.add(member);
        }
        
        classInfo.setMemberCount(members.size());

        // 4. 获取班级作业
        List<AppClassDetailRespVO.ClassHomework> homeworks = getClassHomeworks(classId, userId);

        // 5. 获取班级打卡
        List<AppClassDetailRespVO.ClassCheckin> checkins = getClassCheckins(classId, userId);

        detail.setClassInfo(classInfo);
        detail.setMembers(members);
        detail.setHomeworks(homeworks);
        detail.setCheckins(checkins);

        return detail;
    }

    /**
     * 获取班级作业列表
     */
    private List<AppClassDetailRespVO.ClassHomework> getClassHomeworks(Integer classId, Long userId) {
        List<AppClassDetailRespVO.ClassHomework> homeworks = new ArrayList<>();
        
        // 查询班级作业
        List<HomeworksDO> homeworkDOs = homeworksMapper.selectByClassId(classId);
        
        for (HomeworksDO homeworkDO : homeworkDOs) {
            AppClassDetailRespVO.ClassHomework homework = new AppClassDetailRespVO.ClassHomework();
            homework.setHomeworkId(homeworkDO.getHomeworkId());
            homework.setTitle(homeworkDO.getTitle());
            homework.setDescription(homeworkDO.getDescription());
            homework.setCreateTime(homeworkDO.getCreateTime());
            
            // 设置作业要求字段（新增）
            homework.setRequirement(homeworkDO.getRequirement());
            
            // 暂时设置默认值，后续可扩展
            homework.setCompletedCount(0);
            homework.setStatus(0);
            
            homeworks.add(homework);
        }
        
        return homeworks;
    }

    /**
     * 获取班级打卡列表
     */
    private List<AppClassDetailRespVO.ClassCheckin> getClassCheckins(Integer classId, Long userId) {
        List<AppClassDetailRespVO.ClassCheckin> checkins = new ArrayList<>();
        
        // 获取班级成员ID列表
        List<ClassMembersDO> members = classMembersMapper.selectList(ClassMembersDO::getClassesId, classId);
        List<Long> memberUserIds = members.stream()
            .filter(m -> !m.getDeleted())
            .map(m -> Long.valueOf(m.getUserId()))
            .collect(Collectors.toList());
        
        if (memberUserIds.isEmpty()) {
            return checkins;
        }
        
        // 查询班级成员的打卡记录
        List<CheckInDO> allCheckins = checkInMapper.selectByUserIds(memberUserIds);
        
        // 按日期分组
        Map<String, List<CheckInDO>> checkinsByDate = allCheckins.stream()
            .collect(Collectors.groupingBy(
                checkin -> checkin.getCreateTime().toLocalDate().toString()
            ));
        
        // 构建打卡详情
        for (Map.Entry<String, List<CheckInDO>> entry : checkinsByDate.entrySet()) {
            String date = entry.getKey();
            List<CheckInDO> dayCheckins = entry.getValue();
            
            AppClassDetailRespVO.ClassCheckin checkin = new AppClassDetailRespVO.ClassCheckin();
            checkin.setCheckinId(dayCheckins.get(0).getClockId());
            checkin.setTitle("每日打卡 - " + date);
            checkin.setRequirement("完成绘本阅读打卡");
            checkin.setCheckinDate(dayCheckins.get(0).getCreateTime());
            checkin.setCreateTime(dayCheckins.get(0).getCreateTime());
            checkin.setCheckinCount(dayCheckins.size());
            
            // 检查当前用户是否打卡
            boolean userChecked = dayCheckins.stream()
                .anyMatch(c -> c.getUserId().equals(userId));
            checkin.setStatus(userChecked ? 1 : 0);
            
            checkins.add(checkin);
        }
        
        // 按日期倒序排列
        checkins.sort((a, b) -> b.getCheckinDate().compareTo(a.getCheckinDate()));
        
        return checkins;
    }

    @Override
    public List<AppClassesRespVO> getMyClasses(Long userId) {
        System.out.println("=== getMyClasses 调试信息 ===");
        System.out.println("查询用户ID: " + userId);
        
        List<AppClassesRespVO> result = new ArrayList<>();
        
        // 1. 获取用户创建的班级（过滤已删除的）
        // 使用新的查询包装器避免缓存问题
        LambdaQueryWrapper<ClassesDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ClassesDO::getUserId, userId.intValue())
                   .eq(ClassesDO::getDeleted, false);
        List<ClassesDO> createdClasses = classesMapper.selectList(queryWrapper);
        System.out.println("用户创建的班级数量: " + createdClasses.size());
        for (ClassesDO classDO : createdClasses) {
            System.out.println("创建的班级: ID=" + classDO.getClassesId() + ", 名称=" + classDO.getCname() + ", 已删除=" + classDO.getDeleted());
            AppClassesRespVO classVO = BeanUtils.toBean(classDO, AppClassesRespVO.class);
            classVO.setUserId(Long.valueOf(classDO.getUserId()));
            result.add(classVO);
        }
        
        // 2. 获取用户加入的班级（过滤已删除的成员关系和已删除的班级）
        List<ClassMembersDO> memberClasses = classMembersMapper.selectList(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getUserId, userId.intValue())
                .eq(ClassMembersDO::getDeleted, false)
        );
        System.out.println("用户加入的班级成员关系数量: " + memberClasses.size());
        for (ClassMembersDO memberDO : memberClasses) {
            ClassesDO classDO = classesMapper.selectById(memberDO.getClassesId());
            if (classDO != null) {
                System.out.println("加入的班级: ID=" + classDO.getClassesId() + ", 名称=" + classDO.getCname() + ", 已删除=" + classDO.getDeleted() + ", 班主任ID=" + classDO.getUserId());
            }
            // 检查班级是否存在且未被删除，并且不是自己创建的班级（避免重复）
            if (classDO != null && !classDO.getDeleted() && !classDO.getUserId().equals(userId.intValue())) {
                AppClassesRespVO classVO = BeanUtils.toBean(classDO, AppClassesRespVO.class);
                classVO.setUserId(Long.valueOf(classDO.getUserId()));
                result.add(classVO);
            }
        }
        
        // 3. 去重（防止重复数据）
        List<AppClassesRespVO> finalResult = result.stream()
            .collect(Collectors.toMap(
                AppClassesRespVO::getClassesId,
                Function.identity(),
                (existing, replacement) -> existing))
            .values()
            .stream()
            .sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime())) // 按创建时间倒序
            .collect(Collectors.toList());
            
        System.out.println("最终返回的班级数量: " + finalResult.size());
        for (AppClassesRespVO classVO : finalResult) {
            System.out.println("返回班级: ID=" + classVO.getClassesId() + ", 名称=" + classVO.getCname());
        }
        System.out.println("=== getMyClasses 调试信息结束 ===");
        
        return finalResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String joinClass(Integer command, Long userId) {
        // 1. 根据口令查找班级
        ClassesDO classesDO = classesMapper.selectOne(ClassesDO::getCommand, command);
        if (classesDO == null) {
            throw exception(BANJI_NOT_EXISTS);
        }

        // 2. 检查是否为班级创建者
        if (classesDO.getUserId().equals(userId.intValue())) {
            return "您是班级创建者，无需加入";
        }

        // 3. 检查是否已经是班级成员
        List<ClassMembersDO> existingMembers = classMembersMapper.selectList(
            ClassMembersDO::getClassesId, classesDO.getClassesId(),
            ClassMembersDO::getUserId, userId.intValue()
        );
        
        for (ClassMembersDO member : existingMembers) {
            if (!member.getDeleted()) {
                return "您已经是班级成员了";
            }
        }

        // 4. 加入班级
        AppClassMembersSaveReqVO memberReqVO = new AppClassMembersSaveReqVO();
        memberReqVO.setUserId(userId);
        memberReqVO.setClassesId(classesDO.getClassesId());
        
        try {
            classMembersService.InsertClassMembers(memberReqVO);
            return "成功加入班级：" + classesDO.getCname();
        } catch (Exception e) {
            throw exception(BANJI_JOIN_FAILED);
        }
    }

    @Override
    public boolean hasUserJoinedAnyClass(Long userId) {
        // 1. 检查用户是否创建了班级（过滤已删除的）
        List<ClassesDO> createdClasses = classesMapper.selectList(
            Wrappers.<ClassesDO>lambdaQuery()
                .eq(ClassesDO::getUserId, userId.intValue())
                .eq(ClassesDO::getDeleted, false)
        );
        if (!createdClasses.isEmpty()) {
            return true;
        }
        
        // 2. 检查用户是否加入了班级（过滤已删除的成员关系，并检查班级是否存在且未删除）
        List<ClassMembersDO> memberClasses = classMembersMapper.selectList(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getUserId, userId.intValue())
                .eq(ClassMembersDO::getDeleted, false)
        );
        for (ClassMembersDO member : memberClasses) {
            // 检查对应的班级是否存在且未被删除
            ClassesDO classDO = classesMapper.selectById(member.getClassesId());
            if (classDO != null && !classDO.getDeleted()) {
                return true;
            }
        }
        
        return false;
    }

    @Override
    public AppClassesRespVO previewClassByCommand(Integer command) {
        // 1. 根据口令查找班级
        ClassesDO classesDO = classesMapper.selectOne(ClassesDO::getCommand, command);
        if (classesDO == null) {
            throw exception(BANJI_NOT_EXISTS);
        }

        // 2. 转换为返回对象
        AppClassesRespVO classInfo = BeanUtils.toBean(classesDO, AppClassesRespVO.class);
        classInfo.setUserId(Long.valueOf(classesDO.getUserId()));

        // 3. 获取班级成员数量
        List<ClassMembersDO> members = classMembersMapper.selectList(
            ClassMembersDO::getClassesId, classesDO.getClassesId(),
            ClassMembersDO::getDeleted, false
        );
        classInfo.setMemberCount(members.size() + 1); // +1 包含创建者

        return classInfo;
    }

    @Override
    public List<AppCheckInEnhancedRespVO> getClassCheckinsEnhanced(Integer classId, Long userId) {
        List<AppCheckInEnhancedRespVO> enhancedList = new ArrayList<>();
        
        // 获取班级成员ID列表
        List<ClassMembersDO> members = classMembersMapper.selectList(ClassMembersDO::getClassesId, classId);
        List<Long> memberUserIds = members.stream()
            .filter(m -> !m.getDeleted())
            .map(m -> Long.valueOf(m.getUserId()))
            .collect(Collectors.toList());
        
        if (memberUserIds.isEmpty()) {
            return enhancedList;
        }
        
        // 查询班级成员的打卡记录，按时间倒序
        List<CheckInDO> allCheckins = checkInMapper.selectByUserIds(memberUserIds);
        
        // 为每个打卡记录构建增强信息
        for (CheckInDO checkIn : allCheckins) {
            AppCheckInEnhancedRespVO enhancedVO = new AppCheckInEnhancedRespVO();
            enhancedVO.setClockId(checkIn.getClockId());
            enhancedVO.setContent(checkIn.getContent());
            enhancedVO.setDayCount(checkIn.getDayCount());
            enhancedVO.setCreateTime(checkIn.getCreateTime());
            
            // 获取用户信息
            userDTODO user = userService.getuserDTO(checkIn.getUserId());
            if (user != null) {
                AppCheckInEnhancedRespVO.UserInfo userInfo = new AppCheckInEnhancedRespVO.UserInfo();
                userInfo.setUserId(user.getUserId());
                userInfo.setNickName(user.getNickname());
                userInfo.setAvatar(user.getAvatarUrl() != null ? user.getAvatarUrl() : UserConstants.DEFAULT_AVATAR_URL);
                userInfo.setIsVip(user.getIsMember());
                enhancedVO.setUserInfo(userInfo);
            }
            
            // 获取书籍信息
            if (checkIn.getBookList() != null && !checkIn.getBookList().isEmpty()) {
                List<Integer> bookIds = JSON.parseArray(checkIn.getBookList(), Integer.class);
                List<AppCheckInEnhancedRespVO.BookInfo> bookInfoList = new ArrayList<>();
                
                for (Integer bookId : bookIds) {
                    AppBooksRespVO book = booksService.getByBookId(bookId, null);
                    if (book != null) {
                        AppCheckInEnhancedRespVO.BookInfo bookInfo = new AppCheckInEnhancedRespVO.BookInfo();
                        bookInfo.setBookId(book.getBookId());
                        bookInfo.setTitle(book.getTitle());
                        bookInfo.setImage(book.getImage());
                        bookInfo.setCollectionId(book.getCollectionId());
                        bookInfo.setCreator(book.getCreator());
                        bookInfoList.add(bookInfo);
                    }
                }
                enhancedVO.setBookList(bookInfoList);
            }
            
            enhancedList.add(enhancedVO);
        }
        
        // 按时间倒序排列
        enhancedList.sort((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()));
        
        return enhancedList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String quitClass(Integer command, Long userId) {
        // 1. 根据口令查找班级
        ClassesDO classesDO = classesMapper.selectOne(ClassesDO::getCommand, command);
        if (classesDO == null) {
            throw exception(BANJI_NOT_EXISTS);
        }

        // 2. 检查是否为班级创建者（老师不能退出自己的班级）
        if (classesDO.getUserId().equals(userId.intValue())) {
            return "您是班级创建者，不能退出班级。如需解散班级，请使用班级管理功能";
        }

        // 3. 检查是否为班级成员
        List<ClassMembersDO> existingMembers = classMembersMapper.selectList(
            ClassMembersDO::getClassesId, classesDO.getClassesId(),
            ClassMembersDO::getUserId, userId.intValue()
        );
        
        ClassMembersDO currentMember = null;
        for (ClassMembersDO member : existingMembers) {
            if (!member.getDeleted()) {
                currentMember = member;
                break;
            }
        }
        
        if (currentMember == null) {
            return "您不是该班级的成员";
        }

        // 4. 执行退出操作（逻辑删除）
        try {
            currentMember.setDeleted(true);
            classMembersMapper.updateById(currentMember);
            return "成功退出班级：" + classesDO.getCname();
        } catch (Exception e) {
            throw exception(BANJI_QUIT_FAILED);
        }
    }

    @Override
    public List<AppClassMemberRespVO> getClassMembers(Integer classId, Long currentUserId) {
        // 验证班级是否存在
        ClassesDO classInfo = classesMapper.selectById(classId);
        if (classInfo == null) {
            throw exception(BANJI_NOT_EXISTS);
        }
        
        // 获取班级所有成员
        List<ClassMembersDO> members = classMembersMapper.selectList(
            Wrappers.<ClassMembersDO>lambdaQuery()
                .eq(ClassMembersDO::getClassesId, classId)
                .eq(ClassMembersDO::getDeleted, false)
                .orderByAsc(ClassMembersDO::getCreateTime)
        );
        
        List<AppClassMemberRespVO> result = new ArrayList<>();
        
        for (ClassMembersDO member : members) {
            AppClassMemberRespVO memberVO = new AppClassMemberRespVO();
            memberVO.setMemberId(member.getMembersId().longValue());
            memberVO.setUserId(member.getUserId().longValue());
            
            // 获取用户详细信息
            try {
                userDTODO userInfo = userService.getuserDTO(member.getUserId().longValue());
                if (userInfo != null) {
                    memberVO.setName(userInfo.getNickname());
                    memberVO.setNickname(userInfo.getNickname());
                    memberVO.setAvatar(UserConstants.DEFAULT_AVATAR_URL);
                } else {
                    memberVO.setName("未知用户");
                    memberVO.setNickname("未知用户");
                    memberVO.setAvatar(UserConstants.DEFAULT_AVATAR_URL);
                }
            } catch (Exception e) {
                memberVO.setName("未知用户");
                memberVO.setNickname("未知用户");
                memberVO.setAvatar(UserConstants.DEFAULT_AVATAR_URL);
            }
            
            // 判断是否是老师（班主任）
            memberVO.setIsTeacher(classInfo.getUserId().equals(member.getUserId()));
            memberVO.setIsOwner(classInfo.getUserId().equals(member.getUserId()));
            memberVO.setIsCurrentUser(currentUserId.equals(member.getUserId().longValue()));
            memberVO.setJoinTime(member.getCreateTime());
            
            // 添加阅读统计
            AppClassMemberRespVO.ReadingStats stats = new AppClassMemberRespVO.ReadingStats();
            stats.setBooksRead(0);
            stats.setDaysActive(0);
            stats.setCheckInCount(0);
            memberVO.setReadingStats(stats);
            
            result.add(memberVO);
        }
        
        return result;
    }
}
